package com.lucifer.cloud.boot.blog.chat.advisor;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import com.lucifer.cloud.boot.blog.chat.common.MessageWrapper;
import com.lucifer.cloud.boot.blog.chat.database.MpConversationService;
import com.lucifer.cloud.boot.blog.domin.bo.BaseConversation;
import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.messages.Message;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class DbChatMemory implements ChatMemory {

    private final MpConversationService conversationService;

    @Override
    public void add(String conversationId, List<Message> messages) {
        BaseConversation baseConversation = conversationService.getOneOpt(
                new LambdaQueryWrapper<BaseConversation>().eq(BaseConversation::getConversationId, conversationId))
            .orElseThrow(
                () -> new RuntimeException("can not find the conversation , conversation id is %s".formatted(conversationId)));
        List<Message> savedMessages = convert(baseConversation);
        savedMessages.addAll(messages);
        conversationService.update(BaseConversation.builder()
                .content(MessageWrapper.toConversationStr(savedMessages.stream().map(MessageWrapper::new).toList())).build(),
            new LambdaQueryWrapper<BaseConversation>()
                .eq(BaseConversation::getConversationId, conversationId));
    }

    @Override
    public List<Message> get(String conversationId, int lastN) {
        return conversationService.getOneOpt(new LambdaQueryWrapper<BaseConversation>()
                .eq(BaseConversation::getConversationId, conversationId))
            .map(v -> convert(v).stream().limit(lastN).toList())
            .orElse(List.of());
    }

    @Override
    public void clear(String conversationId) {
        conversationService.remove(
            new LambdaQueryWrapper<BaseConversation>().eq(BaseConversation::getConversationId, conversationId));
    }

    private List<Message> convert(BaseConversation conversation) {
        if (!StringUtils.hasText(conversation.getContent())) {
            return new ArrayList<>();
        }
        return MessageWrapper.fromConversationStr(conversation.getContent()).stream().map(MessageWrapper::toMessage).collect(
            Collectors.toList());
    }
}
